package com.qrxl.common.service.impl;

import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectRequest;
import com.qrxl.common.exception.CustomException;
import com.qrxl.common.service.IFileStoreService;
import com.qrxl.commond.AliOssCondition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Conditional;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketTimeoutException;

/**
 * 阿里云oss文件存储
 *
 * @author zhoukun
 */
@Service
@Conditional(AliOssCondition.class)
public final class AliOssFileStoreServiceImpl extends AbstractFileStoreServiceImpl implements IFileStoreService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private static String ACCESS_KEY_ID = "LTAI4GErFr7Qjvzd6HCQkpTb";
    private static String SECRET_ACCESS_KEY = "bO6eKMdy42Es3f3kI87Cp8x6syxSh1";
    private static String BUCKET_NAME = "jgkj-pub-bpy";
    //    private static String ENDPOINT = "oss-cn-guangzhou-internal.aliyuncs.com";
    private static String ENDPOINT = "oss-cn-guangzhou.aliyuncs.com";

    private OSSClient getOssClient() {
        ClientConfiguration conf = new ClientConfiguration();
        conf.setSupportCname(false);
        return new OSSClient(ENDPOINT, ACCESS_KEY_ID, SECRET_ACCESS_KEY, conf);
    }

    @Override
    public String uploadFileBytes(String key, byte[] bytes) throws IOException {
        OSSClient ossClient = getOssClient();
        try (InputStream input = new ByteArrayInputStream(bytes)) {
            ossClient.putObject(new PutObjectRequest(BUCKET_NAME, getOssKey(key), input));
        } finally {
            ossClient.shutdown();
        }
        return key;
    }

    @Override
    public String getMD5String(String path) {
        path = checkKey(path);
        OSSClient ossClient = getOssClient();
        try {
            OSSObject ossObject = ossClient.getObject(BUCKET_NAME, getOssKey(path));
            ObjectMetadata objectMetadata = ossObject.getObjectMetadata();
            return objectMetadata.getETag().toUpperCase();
        } catch (OSSException e) {
            if (e.getErrorCode().equals("NoSuchKey")) {
                logger.info("文件不存在：" + path);
                throw new CustomException("文件不存在");
            } else {
                throw e;
            }
        } finally {
            ossClient.shutdown();
        }
    }

    @Override
    public byte[] realGetFileBytes(String path) throws IOException {
        path = checkKey(path);
        OSSClient ossClient = getOssClient();
        try {
            OSSObject ossObj = ossClient.getObject(BUCKET_NAME, getOssKey(path));
            int dataLength = (int) ossObj.getObjectMetadata().getContentLength();
            byte[] bytes = new byte[dataLength];
            int readCount = 0;
            try (InputStream is = ossObj.getObjectContent()) {
                while (readCount < dataLength) {
                    readCount += is.read(bytes, readCount, dataLength - readCount);
                }
            }
            return bytes;
        } catch (OSSException e) {
            if (e.getErrorCode().equals("NoSuchKey")) {
                logger.info("文件不存在：" + path);
                return new byte[0];
            } else {
                throw e;
            }
        } finally {
            ossClient.shutdown();
        }
    }

    @Override
    public void writeData(HttpServletResponse response, String path) throws IOException {
        path = checkKey(path);
        OSSClient ossClient = getOssClient();
        try {
            OSSObject ossObj = ossClient.getObject(BUCKET_NAME, getOssKey(path));
            int dataLength = (int) ossObj.getObjectMetadata().getContentLength();
            byte[] temp = new byte[1024];
            try (OutputStream outputStream = response.getOutputStream();
                 InputStream inputStream = ossObj.getObjectContent()) {
                response.setContentLength(dataLength);
                response.setContentType(ossObj.getObjectMetadata().getContentType());
                int n;
                while ((n = inputStream.read(temp)) != -1) {
                    outputStream.write(temp, 0, n);
                    outputStream.flush();
                }
            } catch (SocketTimeoutException e) {
                logger.info("客户端未下载完文件断开连接：" + path);
            }
        } catch (OSSException e) {
            if (e.getErrorCode().equals("NoSuchKey")) {
                logger.info("文件不存在：" + path);
                try (OutputStream outputStream = response.getOutputStream();) {
                    response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                    response.setContentType("text/html;charset=utf-8");
                    outputStream.write("文件不存在".getBytes("utf-8"));
                    outputStream.flush();
                }
                return;
            } else {
                throw e;
            }
        } finally {
            ossClient.shutdown();
        }
    }

    @Override
    public boolean fileExist(String key) {
        if (!key.startsWith(PATH_SPLIT + PATH_PREFIX)) {
            return false;
        }
        OSSClient ossClient = getOssClient();
        boolean result = ossClient.doesObjectExist(BUCKET_NAME, getOssKey(key));
        ossClient.shutdown();
        return result;
    }
}
